﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Daphne.GameShared;

namespace GameEngine.MoveGenerators
{
    /// <summary>
    /// Class for generating classic moves and jumps of man
    /// </summary>
    public class ClassicManMoveGenerator: BaseMoveGenerator, IManMoveGenerator
    {
        /// <summary>
        /// Indicates whether a man can jump kings
        /// </summary>
        protected bool _CanJumpKings;


        /// <summary>
        /// Constructor
        /// </summary>
        public ClassicManMoveGenerator(bool canJumpKings = true)
            : base()
        {
            _CanJumpKings = canJumpKings;
        }

        /// <summary>
        /// Get steps of man moving up
        /// </summary>
        protected List<Position> GetManMovesUp(Position figurePos)
        {
            List<Position> list = new List<Position>();
            Position testPos;
            
            testPos = figurePos.NorthEast;
            if (IsPlaceFreeToMove(testPos) == true)
                list.Add(testPos);

            testPos = figurePos.NorthWest;
            if (IsPlaceFreeToMove(testPos) == true)
                list.Add(testPos);

            return list;
        }

        /// <summary>
        /// Gets steps of man moving down
        /// </summary>
        protected List<Position> GetManMovesDown(Position figurePos)
        {
            List<Position> list = new List<Position>();
            Position testPos;

            testPos = figurePos.SouthEast;
            if (IsPlaceFreeToMove(testPos) == true)
                list.Add(testPos);

            testPos = figurePos.SouthWest;
            if (IsPlaceFreeToMove(testPos) == true)
                list.Add(testPos);

            return list;
        }

        /// <summary>
        /// Tests if jump is valid
        /// </summary>
        /// <param name="testPos">free field</param>
        /// <param name="jumpedFigurePos">jumped figure field</param>
        /// <param name="clrMovedFigure">moving figure color</param>
        /// <returns></returns>
        protected bool IsJumpValid(Position testPos, Position jumpedFigurePos, enumFigureColor clrMovedFigure)       
        {
            enumFigureType jumpedFigure = enumFigureType.Nothing;

            if (IsPlaceFreeToMove(testPos) == true)
            {
                jumpedFigure = GameBoard.GetField(jumpedFigurePos);
                if (jumpedFigure != enumFigureType.Nothing)
                {
                    if (jumpedFigure.FigureColor() != clrMovedFigure)
                    {
                        // if can jump kings
                        if(_CanJumpKings)
                            return true;
                        
                        // check if king, then it cannot jump it
                        if (jumpedFigure.IsKing())
                            return false;
                        else
                            return true;                                              
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// Get jumps of man moving up
        /// </summary>
        protected virtual List<Position> GetManJumpsUp(Position figurePos)
        {
            List<Position> list = new List<Position>();

            Position jumpedFigurePos;
            Position testPos;
            enumFigureColor clrMovedFigure = GameBoard.GetField(figurePos).FigureColor();

            jumpedFigurePos = figurePos.NorthEast;
            testPos = jumpedFigurePos.NorthEast;
            if (IsJumpValid(testPos, jumpedFigurePos, clrMovedFigure))
                list.Add(testPos);

            jumpedFigurePos = figurePos.NorthWest;
            testPos = jumpedFigurePos.NorthWest;
            if(IsJumpValid(testPos, jumpedFigurePos, clrMovedFigure))
                list.Add(testPos);


            return list;
        }

        /// <summary>
        /// Get jumps of man moving down
        /// </summary>
        protected virtual List<Position> GetManJumpsDown(Position figurePos)
        {
            List<Position> list = new List<Position>();

            Position jumpedFigurePos;
            Position testPos;
            enumFigureColor clrMovedFigure = GameBoard.GetField(figurePos).FigureColor();

            jumpedFigurePos = figurePos.SouthEast;
            testPos = jumpedFigurePos.SouthEast;
            if (IsJumpValid(testPos, jumpedFigurePos, clrMovedFigure))
                list.Add(testPos);

            jumpedFigurePos = figurePos.SouthWest;
            testPos = jumpedFigurePos.SouthWest;
            if (IsJumpValid(testPos, jumpedFigurePos, clrMovedFigure))
                list.Add(testPos);

            return list;
        }

        /// <summary>
        /// Returns man moves
        /// </summary>
        public List<Position> GetManMoves(Position figure, enumManOrientation eOrientation)
        {
            if (eOrientation == enumManOrientation.Up)
                return GetManMovesUp(figure);
            else
                return GetManMovesDown(figure);
        }

        /// <summary>
        /// Returns man jumps, one step
        /// </summary>
        public List<Position> GetManJumps(Position figure, enumManOrientation eOrientation)
        {
            if (eOrientation == enumManOrientation.Up)
                return GetManJumpsUp(figure);
            else
                return GetManJumpsDown(figure);
        }
    }
}
